package com.yjz.study.http

import com.yjz.common.restful.CallBack
import com.yjz.common.restful.HttpBaseResponse
import com.yjz.common.restful.RequestInfo
import com.yjz.common.restful.JCall
import com.yjz.log.JLog
import okhttp3.FormBody
import okhttp3.MediaType
import okhttp3.RequestBody
import okhttp3.ResponseBody
import org.json.JSONObject
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit

/**
 *作用 : 具体网络请求框架的实现类
 *作者 : yjz
 *时间 : 2025/2/11 15:57
 */
class RetrofitCallFactory(baseUrl: String) : JCall.Factory {
    private var apiService: RetrofitApiService
    private var gsonConvert: GsonConvert

    init {
        // 初始化程序使用的请求卡框架
        val retrofit = Retrofit.Builder()
            .baseUrl(baseUrl)
            .build()

        apiService = retrofit.create(RetrofitApiService::class.java)
        gsonConvert = GsonConvert()
    }

    override fun newCall(requestInfo: RequestInfo): JCall<Any> {
        return RetrofitCall(requestInfo)
    }

    internal inner class RetrofitCall<T>(private val requestInfo: RequestInfo) : JCall<T> {

        // 获取完整的请求地址，例如：http://xxx.xxx.xxx/login
        private val url = requestInfo.endPointUrl()

        override fun execute(): HttpBaseResponse<T> {
            // 创建真正请求框架的请求
            val createRealCall = createRealCall(requestInfo)
            try {
                // 对应的同步执行方法
                val baseResponse = createRealCall.execute()
                // 解析请求的内容返回
                return parseResponse(baseResponse)
            } catch (e: Exception) {
                val response = HttpBaseResponse<T>()
                response.code = -1
                response.msg = e.message
                return response
            }
        }

        override fun enqueue(callback: CallBack<T>) {
            // 创建真正请求框架的请求
            val realCall: Call<ResponseBody> = createRealCall(requestInfo)
            // 对应的异步执行方法
            realCall.enqueue(object : Callback<ResponseBody> {
                override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                    // 解析请求的内容返回 
                    callback.onSuccess(parseResponse(response))
                }

                override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                    // 错误返回
                    callback.onFailed(throwable = t)
                }
            })
        }

        /**
         * 解析请求框架的返回数据并转换成我们自己的实体类
         */
        private fun parseResponse(response: Response<ResponseBody>): HttpBaseResponse<T> {
            JLog.e(requestInfo.endPointUrl())
            var rawData: String? = null
            if (response.isSuccessful) {
                val body: ResponseBody? = response.body()
                if (body != null) {
                    rawData = body.string()
                }
            } else {
                val body: ResponseBody? = response.errorBody()
                if (body != null) {
                    rawData = body.string()
                }
            }
            JLog.e(rawData)
            return gsonConvert.convert(rawData!!, requestInfo.returnType!!)
        }

        /**
         * 创建对应网络请求框架的请求
         */
        private fun createRealCall(request: RequestInfo): Call<ResponseBody> {
            if (request.httpMethod == RequestInfo.METHOD.GET) {
                return apiService.get(request.headers, url, request.parameters)
            } else if (RequestInfo.METHOD.POST == request.httpMethod) {
                val parameters = request.parameters
                val builder = FormBody.Builder()
                val jsonObject = JSONObject()
                if (parameters != null) {
                    for ((key, value) in parameters) {
                        if (request.formPost) {
                            builder.add(key, value)
                        } else {
                            jsonObject.put(key, value)
                        }
                    }
                }
                val requestBody: RequestBody = if (request.formPost) {
                    builder.build()
                } else {
                    RequestBody.create(MediaType.parse("application/json:utf-8"), jsonObject.toString())
                }
                return apiService.post(request.headers, url, requestBody)
            } else {
                throw IllegalStateException("ZRestful only support GET POST for now ,url=" + request.endPointUrl())
            }
        }
    }
}